#include "SerialPortInfo.h"
#include <boost\bind.hpp>
#include <boost\exception\all.hpp>
#include <boost\chrono.hpp>

#include "jni_utile.h"

typedef boost::date_time::subsecond_duration<boost::posix_time::time_duration, 1000> micro_secnd;
extern JavaVM* g_jvm;

SerialPortInfo::SerialPortInfo(serial_port_ptr p, size_t buf_size)
	:stream(buf_size),pserial_port(p)
{
	//this->pserial_port = p;
	read_time_out = false;
}


SerialPortInfo::~SerialPortInfo()
{
}


void SerialPortInfo::timeout_handle(boost::shared_ptr<boost::asio::deadline_timer> t,boost::system::error_code e) {
	if(t.get() == this->timer.get()){
		boost::system::error_code ec;

		this->read_time_out = true;
		this->pserial_port->cancel(e);
		this->timer.reset();
		std::cout << "time out1:";
		std::cout <<e.value()<< e.message()<<std::endl;
	}
}

void SerialPortInfo::async_wait_timeout(JNIEnv *penv, jobject obj, int time) {
	//this->read_time_out = false;
	this->timer.reset(new boost::asio::deadline_timer(pserial_port->get_io_service()));
	this->timer->expires_from_now(micro_secnd(time));

	jobject ghandle = penv->NewGlobalRef(obj);

	this->timer->async_wait(boost::bind(&SerialPortInfo::timeout_handle, this, this->timer, _1));
	/*if (NULL != ghandle) {
		this->timer->async_wait(boost::bind(warp_timeout_handle, g_jvm, ghandle,_1));
	}
	else {
		call_timeout_handle(penv, obj, boost::system::errc::make_error_code(boost::system::errc::not_enough_memory));
	}*/
}

Lock SerialPortInfo::get_lock(JNIEnv* penv, jobject obj) {
	return Lock(new boost::unique_lock<boost::timed_mutex>(this->mutex, boost::chrono::seconds(5)));
}

void SerialPortInfo::cancel_async_wait() {
	boost::system::error_code ec;
	if(this->timer.get() != NULL){
		//this->timer->cancel(ec);
		this->timer.reset();
		//std::cout<<"time2:"<<ec.message()<<std::endl;
	}
}

